/* ===========================================================
* TradeManager : An application to trade strategies for the Java(tm) platform
* ===========================================================
*
* (C) Copyright 2011-2011, by Simon Allen and Contributors.
*
* Project Info: org.trade
*
* This library is free software; you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation; either version 2.1 of the License, or
* (at your option) any later version.
*
* This library is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
* License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
* USA.
*
* [Java is a trademark or registered trademark of Oracle, Inc.
* in the United States and other countries.]
*
* (C) Copyright 2011-2011, by Simon Allen and Contributors.
*
* Original Author: Simon Allen;
* Contributor(s): -;
*
* Changes
* -------
*
*/
package org.trade.persistent.dao;
import java.time.ZonedDateTime;
import java.util.ArrayList;
import java.util.List;
import javax.ejb.Stateless;
import javax.persistence.EntityManager;
import javax.persistence.TypedQuery;
import javax.persistence.criteria.CriteriaBuilder;
import javax.persistence.criteria.CriteriaQuery;
import javax.persistence.criteria.Expression;
import javax.persistence.criteria.Join;
import javax.persistence.criteria.Predicate;
import javax.persistence.criteria.Root;
import org.trade.core.dao.EntityManagerHelper;
/**
*/
@Stateless
public class TradingdayHome {
public TradingdayHome() {
}
/**
* Method persist. This method saves all the trade-strategies for all the
* tradingdays from the Trading Tab.
*
* @param detachedInstance
* Tradingday as set of tradingdays with associated
* tradestrategies.
* @throws Exception
*/
public void persist(final Tradingday detachedInstance) throws Exception {
try {
EntityManager entityManager = EntityManagerHelper.getEntityManager();
entityManager.getTransaction().begin();
/*
* Check the incoming tradingday to see if it exists if it does
* merge with the persisted one if not persist.
*/
Tradingday tradingday = null;
if (null == detachedInstance.getIdTradingDay()) {
tradingday = this.findTradingdayByOpenCloseDate(detachedInstance.getOpen(),
detachedInstance.getClose());
if (null == tradingday) {
entityManager.persist(detachedInstance);
} else {
detachedInstance.setIdTradingDay(tradingday.getIdTradingDay());
detachedInstance.setVersion(tradingday.getVersion());
tradingday = entityManager.merge(detachedInstance);
}
entityManager.getTransaction().commit();
} else {
tradingday = entityManager.merge(detachedInstance);
entityManager.getTransaction().commit();
detachedInstance.setVersion(tradingday.getVersion());
}
for (Tradestrategy tradestrategy : detachedInstance.getTradestrategies()) {
// If it has trades do nothing
if (tradestrategy.getTradeOrders().isEmpty() && tradestrategy.isDirty()) {
entityManager.getTransaction().begin();
/*
* If the tradingday existed use the persisted version.
*/
if (null != tradingday) {
tradestrategy.setTradingday(tradingday);
}
/*
* The strategy will always exist as these cannot be created
* via this tab, as they are a drop down list. So find the
* persisted one and set this.
*/
Strategy strategy = this.findStrategyByName(tradestrategy.getStrategy().getName());
if (null != strategy) {
tradestrategy.setStrategy(strategy);
}
/*
* Check to see if the contract exists if it does merge and
* set the new persisted one. If no persist the contract.
*/
Contract contract = this.findContractByUniqueKey(tradestrategy.getContract().getSecType(),
tradestrategy.getContract().getSymbol(), tradestrategy.getContract().getExchange(),
tradestrategy.getContract().getCurrency(), tradestrategy.getContract().getExpiry());
if (null != contract) {
tradestrategy.setContract(contract);
}
/*
* Persist or merge the tradestrategy.
*/
if (null == tradestrategy.getIdTradeStrategy()) {
entityManager.persist(tradestrategy);
entityManager.getTransaction().commit();
} else {
Tradestrategy instance = entityManager.merge(tradestrategy);
entityManager.getTransaction().commit();
tradestrategy.setVersion(instance.getVersion());
}
tradestrategy.setDirty(false);
}
}
entityManager.getTransaction().begin();
List<Tradestrategy> tradestrategies = findTradestrategyByIdTradingday(detachedInstance.getIdTradingDay());
for (Tradestrategy tradestrategy : tradestrategies) {
boolean exists = false;
for (Tradestrategy newTradestrategy : detachedInstance.getTradestrategies()) {
if (newTradestrategy.equals(tradestrategy)) {
exists = true;
break;
}
}
if (!exists) {
if (tradestrategy.getTradeOrders().isEmpty()) {
entityManager.remove(tradestrategy);
} else {
throw new Exception("The following Contract:" + tradestrategy.getContract().getSymbol()
+ " Strategy:" + tradestrategy.getStrategy().getName()
+ " already exists with trades. \n Please delete orders before removing.");
}
}
}
entityManager.getTransaction().commit();
detachedInstance.setDirty(false);
} catch (Exception re) {
EntityManagerHelper.logError("Error saving Tradingdays: " + re.getMessage(), re);
EntityManagerHelper.rollback();
throw re;
} finally {
EntityManagerHelper.close();
}
}
/**
* Method findTradingdayById.
*
* @param id
* Integer
* @return Tradingday
*/
public Tradingday findTradingdayById(Integer id) {
try {
EntityManager entityManager = EntityManagerHelper.getEntityManager();
entityManager.getTransaction().begin();
Tradingday instance = entityManager.find(Tradingday.class, id);
if (null != instance) {
for (Tradestrategy tradestrategy : instance.getTradestrategies()) {
tradestrategy.getStrategy().getIndicatorSeries().size();
tradestrategy.getTradeOrders().size();
}
}
entityManager.getTransaction().commit();
return instance;
} catch (Exception re) {
EntityManagerHelper.rollback();
throw re;
} finally {
EntityManagerHelper.close();
}
}
/**
* Method findTradingdaysByDateRange.
*
* @param startDate
* ZonedDateTime
* @param endDate
* ZonedDateTime
* @return Tradingdays
*/
public Tradingdays findTradingdaysByDateRange(ZonedDateTime startDate, ZonedDateTime endDate) {
try {
EntityManager entityManager = EntityManagerHelper.getEntityManager();
entityManager.getTransaction().begin();
Tradingdays tradingdays = new Tradingdays();
CriteriaBuilder builder = entityManager.getCriteriaBuilder();
CriteriaQuery<Tradingday> query = builder.createQuery(Tradingday.class);
Root<Tradingday> from = query.from(Tradingday.class);
query.select(from);
query.orderBy(builder.desc(from.get("open")));
List<Predicate> predicates = new ArrayList<Predicate>();
if (null != startDate) {
Predicate predicate = builder.greaterThanOrEqualTo(from.get("open").as(ZonedDateTime.class), startDate);
predicates.add(predicate);
}
if (null != endDate) {
Predicate predicate = builder.lessThanOrEqualTo(from.get("open").as(ZonedDateTime.class), endDate);
predicates.add(predicate);
}
query.where(predicates.toArray(new Predicate[] {}));
TypedQuery<Tradingday> typedQuery = entityManager.createQuery(query);
List<Tradingday> items = typedQuery.getResultList();
for (Tradingday tradingday : items) {
tradingdays.add(tradingday);
for (Tradestrategy tradestrategy : tradingday.getTradestrategies()) {
tradestrategy.getTradeOrders().size();
tradestrategy.getPortfolio().getPortfolioAccounts().size();
tradestrategy.getStrategy().getIndicatorSeries().size();
}
}
entityManager.getTransaction().commit();
return tradingdays;
} catch (Exception re) {
EntityManagerHelper.rollback();
throw re;
} finally {
EntityManagerHelper.close();
}
}
/**
* Method findByOpen.
*
* @param openDate
* ZonedDateTime
* @param closeDate
* ZonedDateTime
* @return Tradingday
*/
public Tradingday findByOpenCloseDate(ZonedDateTime openDate, ZonedDateTime closeDate) {
try {
EntityManager entityManager = EntityManagerHelper.getEntityManager();
entityManager.getTransaction().begin();
CriteriaBuilder builder = entityManager.getCriteriaBuilder();
CriteriaQuery<Tradingday> query = builder.createQuery(Tradingday.class);
Root<Tradingday> from = query.from(Tradingday.class);
query.select(from);
if (null != openDate)
query.where(builder.equal(from.get("open"), openDate));
if (null != closeDate)
query.where(builder.equal(from.get("close"), closeDate));
List<Tradingday> items = entityManager.createQuery(query).getResultList();
for (Tradingday tradingday : items) {
for (Tradestrategy tradestrategy : tradingday.getTradestrategies()) {
tradestrategy.getTradeOrders().size();
tradestrategy.getStrategy().getIndicatorSeries().size();
}
}
entityManager.getTransaction().commit();
if (items.size() > 0) {
return items.get(0);
}
return null;
} catch (Exception re) {
EntityManagerHelper.rollback();
throw re;
} finally {
EntityManagerHelper.close();
}
}
/**
* Method findStrategyByName.
*
* @param name
* String
* @return Strategy
*/
private Strategy findStrategyByName(String name) {
try {
EntityManager entityManager = EntityManagerHelper.getEntityManager();
CriteriaBuilder builder = entityManager.getCriteriaBuilder();
CriteriaQuery<Strategy> query = builder.createQuery(Strategy.class);
Root<Strategy> from = query.from(Strategy.class);
query.select(from);
query.where(builder.equal(from.get("name"), name));
List<Strategy> items = entityManager.createQuery(query).getResultList();
if (items.size() > 0) {
for (Strategy itme : items) {
itme.getIndicatorSeries().size();
}
return items.get(0);
}
return null;
} catch (Exception re) {
throw re;
}
}
/**
* Method findTradingdayByOpenDate.
*
* @param openDate
* ZonedDateTime
* @param closeDate
* ZonedDateTime
*
* @return Tradingday
*/
private Tradingday findTradingdayByOpenCloseDate(ZonedDateTime openDate, ZonedDateTime closeDate) {
try {
EntityManager entityManager = EntityManagerHelper.getEntityManager();
CriteriaBuilder builder = entityManager.getCriteriaBuilder();
CriteriaQuery<Tradingday> query = builder.createQuery(Tradingday.class);
Root<Tradingday> from = query.from(Tradingday.class);
query.select(from);
if (null != openDate)
query.where(builder.equal(from.get("open"), openDate));
if (null != closeDate)
query.where(builder.equal(from.get("close"), closeDate));
List<Tradingday> items = entityManager.createQuery(query).getResultList();
if (items.size() > 0) {
return items.get(0);
}
return null;
} catch (Exception re) {
throw re;
}
}
/**
* Method findTradestrategyByDate.
*
* @param open
* Date
* @return List<Tradestrategy>
*/
private List<Tradestrategy> findTradestrategyByIdTradingday(Integer idTradingday) {
try {
EntityManager entityManager = EntityManagerHelper.getEntityManager();
CriteriaBuilder builder = entityManager.getCriteriaBuilder();
CriteriaQuery<Tradestrategy> query = builder.createQuery(Tradestrategy.class);
Root<Tradestrategy> from = query.from(Tradestrategy.class);
query.select(from);
List<Predicate> predicates = new ArrayList<Predicate>();
if (null != idTradingday) {
Join<Tradestrategy, Tradingday> tradingday = from.join("tradingday");
Predicate predicate = builder.equal(tradingday.get("idTradingDay"), idTradingday);
predicates.add(predicate);
}
query.where(predicates.toArray(new Predicate[] {}));
TypedQuery<Tradestrategy> typedQuery = entityManager.createQuery(query);
List<Tradestrategy> items = typedQuery.getResultList();
return items;
} catch (Exception re) {
throw re;
}
}
/**
* Method findContractByUniqueKey.
*
* @param SECType
* String
* @param symbol
* String
* @param exchange
* String
* @param currency
* String
* @param expiryDate
* Date
* @return Contract
*/
private Contract findContractByUniqueKey(String SECType, String symbol, String exchange, String currency,
ZonedDateTime expiryDate) {
try {
EntityManager entityManager = EntityManagerHelper.getEntityManager();
CriteriaBuilder builder = entityManager.getCriteriaBuilder();
CriteriaQuery<Contract> query = builder.createQuery(Contract.class);
Root<Contract> from = query.from(Contract.class);
query.select(from);
List<Predicate> predicates = new ArrayList<Predicate>();
if (null != SECType) {
Predicate predicate = builder.equal(from.get("secType"), SECType);
predicates.add(predicate);
}
if (null != symbol) {
Predicate predicate = builder.equal(from.get("symbol"), symbol);
predicates.add(predicate);
}
if (null != exchange) {
Predicate predicate = builder.equal(from.get("exchange"), exchange);
predicates.add(predicate);
}
if (null != currency) {
Predicate predicate = builder.equal(from.get("currency"), currency);
predicates.add(predicate);
}
if (null != expiryDate) {
Integer yearExpiry = expiryDate.getYear();
Expression<Integer> year = builder.function("year", Integer.class, from.get("expiry"));
Predicate predicateYear = builder.equal(year, yearExpiry);
predicates.add(predicateYear);
Integer monthExpiry = expiryDate.getMonthValue();
Expression<Integer> month = builder.function("month", Integer.class, from.get("expiry"));
Predicate predicateMonth = builder.equal(month, new Integer(1 + monthExpiry.intValue()));
predicates.add(predicateMonth);
}
query.where(predicates.toArray(new Predicate[] {}));
TypedQuery<Contract> typedQuery = entityManager.createQuery(query);
List<Contract> items = typedQuery.getResultList();
if (items.size() > 0) {
return items.get(0);
}
return null;
} catch (Exception re) {
throw re;
}
}
}